	
// main canvas which is static, does not move or resize
// this canvas is needed for redraw(to get rid of artifacts)
var mainCanvas = null;
		
// size of the screen 
// somehow get this from the device

// constants
var NUM_COLUMNS = 3;
var NUM_BANNERS = 5;
var DISK_CLASS_NAME = "disk";
var COLUMN_CLASS_NAME = "bar";

// global variables
var bannerIndex = 0; // current index of the banner
var serverURL = "http://localhost";
var serverPort = 80;
var bannerNames = ["banners/banner1.jpg", "banners/banner2.jpg", "banners/banner3.jpg", "banners/banner4.jpg", "banners/banner5.jpg"];
var arrayDisks = new Array();
var arrayColumns = new Array();
var numOfDisks = -1;
var numOfMoves = 0;
var timerID = null;
var timerMin = 0;
var timerSec = 0;

// global varibles used for mouse dragging
var m_startX = 0; // mouse starting positions 
var m_startY = 0; 
var m_offsetX = 0; // current element offset 
var m_offsetY = 0; 
var m_dragElement = null; // needs to be passed from OnMouseDown to OnMouseMove 
var m_oldZIndex = 0; // we temporarily increase the z-index during drag 
var m_oldX = 0; // old top coordinate of the image before it started moving
var m_oldY = 0;
var m_oldCol = null; // the column disk was in before moving
var dragging = false;

window.onload=function(){
	// update the banner
	// this will trigger a background "thread" which keeps updating the
	// image after 60 seconds
    updateBanner();
}

/*
 * Column class
 */
function Column() {
	// variables
    this.index = -1;
	this.disks = new Array(); // array of disks
	this.colElement = null;

	// functions
	this.push = push;
	this.pop = pop;
    this.setIndex = setIndex;
    this.getIndex = getIndex;

    function setIndex(i){
    	this.index = i;
    }
    
    function getIndex()
    {
        return this.index;
    }
	
	function push(disk)
	{
		var newDisk = disk;
		// if this column is empty we can put anything
		if (this.disks.length == 0){
			// add the element in the document
			this.colElement.appendChild(disk.diskElement);
			this.disks.push(newDisk);
			return true;
		}
		// check if we can place this disk in this column
		var topDisk = this.disks[this.disks.length - 1];
		if (topDisk != null){
			if (topDisk.getSize() > newDisk.getSize()){
				this.disks.push(newDisk);
				// add the element in the document
				this.colElement.insertBefore(disk.diskElement, this.colElement.firstChild);
				return true;
			}
		}
		return false;
	}

	function pop()
	{
		// remove the element and from the disk and document
//		this.colElement.removeChild(this.colElement.firstChild);
		return this.disks.pop();			
	}
}

/*
 * Disk class
 */
function Disk(){
	// variables
	this.size = -1;
	this.diskElement = null;

	// functions
	this.setSize = setSize;
    this.getSize = getSize;

    function setSize(s){
    	this.size = s;
    }
    
    function getSize()
    {
        return this.size;
    }
}

// initialize the game component
function initialize(){
	setStatusText("Game Started");
	numOfMoves = 0;
	constUpdateNumberOfMoves()
	initTimer();
	// initialize the columns
	for (var i = 0; i < NUM_COLUMNS; i++){
		arrayColumns[i] = new Column();
		arrayColumns[i].index = i;
		arrayColumns[i].colElement = document.getElementById("gameArea" + (i + 1));
	}
	
	//Clear out the gaming area first
	var gameA = document.getElementById('gameArea1');
	while (gameA.firstChild) {
		gameA.removeChild( gameA.firstChild );
	}
	gameA = document.getElementById('gameArea2');
	while (gameA.firstChild) {
		gameA.removeChild( gameA.firstChild );
	}
	gameA = document.getElementById('gameArea3');
	while (gameA.firstChild) {
		gameA.removeChild( gameA.firstChild );
	}
	
	// initialize the disks
	numOfDisks = document.getElementById("numbDisks").value;
	var dWidth = 100;
	for (var i = 0; i < numOfDisks; i++){
		// init the disk object
		arrayDisks[i] = new Disk();
		// set the size backwards so it goes in the stack in correct order
		// lightest at the top, heaviest at the bottom
		arrayDisks[i].size = numOfDisks - i;
		// init the html element for disk
		var block = document.createElement("img");
		block.setAttribute("class", DISK_CLASS_NAME);
		block.setAttribute("src", "res/b" + (i+1) + ".png");
		block.setAttribute("width", dWidth + "px");
		block.setAttribute("height", "20px");

		arrayDisks[i].diskElement = block;
		dWidth = Math.floor(dWidth * 0.9);
		var marginLeft = (100 - dWidth)/2;
        block.style.margin = "0px " + marginLeft + "px 0px";

		// add the disks to the first column
		arrayColumns[0].disks.push(arrayDisks[i]);
		if (i == 0){
			arrayColumns[0].colElement.appendChild(block);
		}
		else {
			arrayColumns[0].colElement.insertBefore(block, arrayDisks[i-1].diskElement);
		}
	}
	
	// initialize for drag and drop
	document.onclick = moveDisk;

	updateTimer(); // start the timer
}

function moveDisk(e){
	var target = e.target;
	if (target.getAttribute("class") == DISK_CLASS_NAME){
		// figure out which column pointer is under
		var col = checkMouseOverCol(e.clientX, e.clientY);
		if (!dragging){
			var temp = arrayColumns[col].disks;
			if(target != temp[temp.length-1].diskElement)
				return;
			dragging = true;
			// save the old coordinate of the image
			m_oldX = parseToNumber(target.style.left);
			m_oldY = parseToNumber(target.style.top);
			m_oldCol = checkMouseOverCol(e.clientX, e.clientY);
			// get the mouse position
			m_startX = e.clientX;
			m_startY = e.clientY;
			// get the offset of the element
			m_offsetX = parseToNumber(target.style.left);
			m_offsetY = parseToNumber(target.style.top);
			// make the dragging item top of the layer
			m_oldZIndex = target.style.zIndex;
			target.style.zIndex = 10000;// just choose a big number
			// keep track of the item being dragged
			m_dragElement = target;
			document.onmousemove = onMouseMove;
			document.body.focus();
			return false;
		}
		dragging = false;
		if (m_dragElement != null){
			// update the columns and disks
			var diskIndex = findDiskUsingElement(m_dragElement);
			m_dragElement.style.left = '0px';
			m_dragElement.style.top = '0px';		
			
			// check if this is a valid move
			if ((col != null && m_oldCol != col) 
					&& arrayColumns[col].push(arrayDisks[diskIndex])){
				arrayColumns[m_oldCol].pop();
				
				// update the number of moves made
				numOfMoves++;
				updateNumberOfMoves();
				// now check if game is over
				checkGameCondition();
			}
			else {
				// move back to the original image position
				m_dragElement.style.left = m_oldX + 'px';
				m_dragElement.style.top = m_oldY + 'px';
			}			
			// finished dragging
			// do clean up
			m_dragElement.style.zIndex = m_oldZIndex;
			document.onmousemove = null;
			m_dragElement = null;
			m_oldX = null;
			m_oldY = null;
			m_oldCol = null;
			m_oldZIndex = null;
		}
	}
}

function checkGameCondition(){
	if (arrayColumns[1].disks.length == numOfDisks 
			|| arrayColumns[2].disks.length == numOfDisks){
		setStatusText("You Won!");
		// take away control until user restarts the game
		document.onclick = null;
		stopTimer();
		return true;
	}
	return false; 
}

function setStatusText(text){
	document.getElementById("status").innerHTML = text;
}

function updateNumberOfMoves(){
	document.getElementById("moves").innerHTML = "Moves: " + numOfMoves;
}

// a hack to stop number of moves from disappearing
// for some reason on the blackberry browser, number of moves disappears every 10 seconds
function constUpdateNumberOfMoves(){
	document.getElementById("moves").innerHTML = "Moves: " + numOfMoves;
	setTimeout("constUpdateNumberOfMoves()", 1000);
}

function initTimer(){
	timerMin = 0;
	timerSec = 0;
	if (timerID != null){
		clearTimeout(timerID);
		timerID = null;
	}
}

function updateTimer(){
	if (timerSec > 59){
		timerSec = 0;
		timerMin++;
	}
	if (timerSec < 10){
		document.getElementById("timer").innerHTML = timerMin + ":0" + timerSec;
	}
	else {
		document.getElementById("timer").innerHTML = timerMin + ":" + timerSec;
	}
	timerSec++;
	timerID = setTimeout("updateTimer()", 1000);
}

function stopTimer(){
	if (timerID != null){
		clearTimeout(timerID);
	}
}

function getAbsolutX(e) {
	var x = 0;
	while(e != null) {
		x += e.offsetLeft;
		e = e.offsetParent;
	}
	return x;
}

function getAbsolutY(e) {
	var x = 0;
	while(e != null) {
		x += e.offsetTop;
		e = e.offsetParent;
	}
	return x;
}

function findDiskUsingElement(element){
	for (var i = 0; i < numOfDisks; i++){
		if (arrayDisks[i].diskElement == element)
			return i;
	}
	return null;
}

function onMouseMove(e){
	if (m_dragElement != null){
		// perform dragging
		var newLeft = m_offsetX + e.clientX - m_startX;
		var newTop = m_offsetY + e.clientY - m_startY;
		// check for bounds so that disk doesn't go off screen
		m_dragElement.style.left = newLeft + 'px';
		m_dragElement.style.top = newTop + 'px';
	}
}

// figure out which column user wants to add the disk
function checkMouseOverCol(x, y){
	var colEle = null;
	for (var i = 0; i < NUM_COLUMNS; i++){
		colEle = arrayColumns[i].colElement;
		var topX = getAbsolutX(colEle);
		var topY = getAbsolutY(colEle);
		var botX = topX + colEle.offsetWidth;
		var botY = topY + colEle.offsetHeight;
		if ((topX <= x && topY <= y) && (botX >= x && botY >= y)){
			return i;
		}
	}
	return null;
}

function parseToNumber(v){
	var n = parseInt(v);
	return n == null || isNaN(n) ? 0 : n;
}

function updateBanner(){
	if (bannerIndex >= NUM_BANNERS){
		bannerIndex = 0;
	}
	document.getElementById("bannerImg").setAttribute("src", "../" +  bannerNames[bannerIndex++]);
	var temp = document.getElementById("bannerImg");
	setTimeout("updateBanner()", 60000); //TODO: change this to 60000
}